package fr.sedoo.commons.shared.domain;

import java.util.ArrayList;
import java.util.List;

import org.gwtopenmaps.openlayers.client.LonLat;

import com.google.gwt.i18n.client.NumberFormat;

import fr.sedoo.commons.client.message.GeographicalMessages;
import fr.sedoo.commons.client.message.ValidationMessages;
import fr.sedoo.commons.client.util.DoubleUtil;
import fr.sedoo.commons.client.util.StringUtil;
import fr.sedoo.commons.client.widget.editing.ValidationAlert;

public class GeographicBoundingBoxDTO extends AbstractDTO implements HasIdentifier {

	private String northBoundLatitude;
	private String southBoundLatitude;
	private String eastBoundLongitude;
	private String westBoundLongitude;
	private String identifier;

	public String getNorthBoundLatitude() {
		return northBoundLatitude;
	}

	public void setNorthBoundLatitude(String northBoundLatitude) {
		this.northBoundLatitude = northBoundLatitude;
	}

	public String getSouthBoundLatitude() {
		return southBoundLatitude;
	}

	public void setSouthBoundLatitude(String southBoundLatitude) {
		this.southBoundLatitude = southBoundLatitude;
	}

	public String getEastBoundLongitude() {
		return eastBoundLongitude;
	}

	public void setEastBoundLongitude(String eastBoundLongitude) {
		this.eastBoundLongitude = eastBoundLongitude;
	}

	public String getWestBoundLongitude() {
		return westBoundLongitude;
	}

	public void setWestBoundLongitude(String westBoundLongitude) {
		this.westBoundLongitude = westBoundLongitude;
	}

	public String getHash() {
		return "@" + StringUtil.trimToEmpty(getNorthBoundLatitude()) + "|" + StringUtil.trimToEmpty(getSouthBoundLatitude()) + "|" + StringUtil.trimToEmpty(getEastBoundLongitude()) + "|"
				+ StringUtil.trimToEmpty(getWestBoundLongitude());
	}

	@Override
	public List<ValidationAlert> validate() {
		List<ValidationAlert> result = new ArrayList<ValidationAlert>();

		if (!DoubleUtil.checkDouble(getNorthBoundLatitude())) {
			result.add(new ValidationAlert(GeographicalMessages.INSTANCE.mapSelectorNorthLatitude(), ValidationMessages.INSTANCE.numericalData()));
		}

		if (!DoubleUtil.checkDouble(getSouthBoundLatitude())) {
			result.add(new ValidationAlert(GeographicalMessages.INSTANCE.mapSelectorSouthLatitude(), ValidationMessages.INSTANCE.numericalData()));
		}

		if (!DoubleUtil.checkDouble(getEastBoundLongitude())) {
			result.add(new ValidationAlert(GeographicalMessages.INSTANCE.mapSelectorEastLongitude(), ValidationMessages.INSTANCE.numericalData()));
		}

		if (!DoubleUtil.checkDouble(getWestBoundLongitude())) {
			result.add(new ValidationAlert(GeographicalMessages.INSTANCE.mapSelectorWestLongitude(), ValidationMessages.INSTANCE.numericalData()));
		}
		return result;
	}

	public boolean isEmpty() {
		String aux = StringUtil.trimToEmpty(northBoundLatitude) + StringUtil.trimToEmpty(southBoundLatitude) + StringUtil.trimToEmpty(eastBoundLongitude) + StringUtil.trimToEmpty(westBoundLongitude);
		aux = aux.trim();
		if (aux.length() == 0) {
			return true;
		} else {
			return false;
		}
	}

	public LonLat getRightLowerCorner() {
		return new LonLat(NumberFormat.getDecimalFormat().parse(eastBoundLongitude), NumberFormat.getDecimalFormat().parse(southBoundLatitude));
	}

	public LonLat getLeftUpperCorner() {
		return new LonLat(NumberFormat.getDecimalFormat().parse(westBoundLongitude), NumberFormat.getDecimalFormat().parse(northBoundLatitude));
	}

	public LonLat getRightLowerDisplayCorner() {

		double horizontalPadding = getHorizontalPadding();
		double verticalPadding = getVerticalPadding();
		return new LonLat(NumberFormat.getDecimalFormat().parse(eastBoundLongitude) + horizontalPadding, NumberFormat.getDecimalFormat().parse(southBoundLatitude) - verticalPadding);
	}

	public LonLat getLeftUpperDisplayCorner() {
		double horizontalPadding = getHorizontalPadding();
		double verticalPadding = getVerticalPadding();
		return new LonLat(NumberFormat.getDecimalFormat().parse(westBoundLongitude) - horizontalPadding, NumberFormat.getDecimalFormat().parse(northBoundLatitude) + verticalPadding);
	}

	public double getHorizontalPadding() {
		return 0.2 * (NumberFormat.getDecimalFormat().parse(eastBoundLongitude) - NumberFormat.getDecimalFormat().parse(westBoundLongitude));
	}

	public double getVerticalPadding() {
		return 0.2 * (NumberFormat.getDecimalFormat().parse(northBoundLatitude) - NumberFormat.getDecimalFormat().parse(southBoundLatitude));
	}

	public boolean isPoint() {
		if ((getNorthBoundLatitude().compareTo(getSouthBoundLatitude()) == 0) && (getEastBoundLongitude().compareTo(getWestBoundLongitude()) == 0)) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	public String getIdentifier() {
		return identifier;
	}

	public void setIdentifier(String identifier) {
		this.identifier = identifier;
	}

	public boolean isValid() {
		return validate().isEmpty();
	}

}
